/**
 * 
 */
package edu.sjtu.seda.stage;

import edu.sjtu.seda.controller.Controller;
import edu.sjtu.seda.event.EventHandler;
import edu.sjtu.seda.eventqueue.EventQueue;
import edu.sjtu.seda.eventqueue.EventQueueImpl;
import edu.sjtu.seda.log.LogService;
import edu.sjtu.seda.stage.api.StageConfig;
import edu.sjtu.seda.threadpool.ThreadPool;
import edu.sjtu.seda.threadpool.ThreadPoolImpl;
import edu.sjtu.seda.threadpool.StageManager;

/**
 * @author john.zhu
 * 
 */
public class StageWrapperImpl implements StageWrapper {
	private static LogService log = new LogService(StageWrapperImpl.class);

	private EventHandler handler;
	private EventQueue eventQueue;
	private ThreadPool threadPool;
	private Stage stage;
	private StageConfig config;
	private Thread queueThread;

	public StageWrapperImpl(Stage stage, EventHandler handler,
			EventQueue eventQueue, StageManager threadPoolManager,
			Controller controller) {

	}

	public StageWrapperImpl(Stage stage, EventHandler handler,
			StageConfig config) {
		this.config = config;
		this.handler = handler;
		this.eventQueue = new EventQueueImpl(this, config.getEventQueueSize(),
				config.isBatchEnable(), config.getBatchSize());
		this.stage = stage;
		try {
			this.threadPool = new ThreadPoolImpl(this,
					config.getThreadPoolSize());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.sjtu.seda.stage.StageWrapper#getStage()
	 */
	@Override
	public Stage getStage() {
		return this.stage;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.sjtu.seda.stage.StageWrapper#getEventHandler()
	 */
	@Override
	public EventHandler getEventHandler() {
		return this.handler;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.sjtu.seda.stage.StageWrapper#getEventQueue()
	 */
	@Override
	public EventQueue getEventQueue() {
		return this.eventQueue;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.sjtu.seda.stage.StageWrapper#getThreadPoolManager()
	 */
	@Override
	public StageManager getStageManager() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.sjtu.seda.stage.StageWrapper#getController()
	 */
	//TODO
	@Override
	public Controller getController() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.sjtu.seda.stage.StageWrapper#start()
	 */
	@Override
	public void start() {
		if (queueThread != null && queueThread.isAlive()) {
			throw new RuntimeException("Stage " + stage.getName() + " already started!");
		} else {
			log.info("Stage {0} start!",stage.getName());
			queueThread = new Thread(eventQueue, "Queue-" + stage.getName());
			queueThread.start();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.sjtu.seda.stage.StageWrapper#destroy()
	 */
	@Override
	public void destroy() {
		log.info("Stage {0} is being shutdown!",stage.getName());
		this.eventQueue.shutdown();
		/*
		 * TODO event queue shutdown policy
		 * event queue should complete tasks in queue
		 * after a shutdown request
		 * and then stop the thread
		 */
		this.queueThread.stop();
		this.threadPool.shutdown();
	}

	@Override
	public ThreadPool getThreadPool() {
		return this.threadPool;
	}

	@Override
	public StageConfig getConfig() {
		return this.config;
	}

	@Override
	public boolean isTerminated() {
		return false;
	}

}
